package org.whmmm.util.httputil.config;

import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.List;
import java.util.Map;

/**
 * <br/><br/>
 * 创建时间: 2020/5/14 11:26
 *
 * @author whmmm
 */
public class BaseRequest {

    public static final BaseRequest CACHE_REQUEST = new BaseRequest();

    /**
     * <b> https 请求 </b>
     *
     * @param requestUrl
     * @param requestMethod
     * @param param
     * @param header
     * @param cookie
     * @param responseHeader
     * @param responseCookie
     * @return
     */
    public String httpsRequest(String requestUrl, String requestMethod, String param,
                               List<HttpHeader> header,
                               List<HttpHeader> cookie,

                               Map<String, String> responseHeader,
                               Map<String, String> responseCookie

    ) {
        try {
            //创建SSLContext
            SSLContext sslContext = SSLContext.getInstance("SSL");
            TrustManager[] tm = IgnoreSslX509TrustManager.TRUST_MANAGER;
            //初始化
            sslContext.init(null, tm, new java.security.SecureRandom());

            //获取SSLSocketFactory对象
            SSLSocketFactory ssf = sslContext.getSocketFactory();
            URL url = new URL(requestUrl);
            HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();

            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);
            setRequestHeaderAndCookie(conn, header, cookie);
            //设置当前实例使用的SSLSoctetFactory
            conn.setSSLSocketFactory(ssf);

            return doRequest(conn, requestMethod, param, responseHeader, responseCookie);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * http 请求
     *
     * @param requestUrl
     * @param requestMethod
     * @param param
     * @param header
     * @param cookie
     * @param responseHeader
     * @param responseCookie
     * @return
     */
    public String httpRequest(String requestUrl, String requestMethod, String param,
                              List<HttpHeader> header,
                              List<HttpHeader> cookie,

                              Map<String, String> responseHeader,
                              Map<String, String> responseCookie) {

        try {

            URL url = new URL(requestUrl);
            HttpURLConnection conn = (HttpURLConnection) url.openConnection();
            setRequestHeaderAndCookie(conn, header, cookie);
            conn.setDoOutput(true);
            conn.setDoInput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod(requestMethod);

            return doRequest(conn, requestMethod, param, responseHeader, responseCookie);

        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }


    protected void setRequestHeaderAndCookie(
            HttpURLConnection conn, List<HttpHeader> header,
            List<HttpHeader> cookie) {
        for (HttpHeader item : header) {
            conn.setRequestProperty(item.getKey(), item.getValue());
        }
        StringBuilder sb = new StringBuilder();
        HttpHeader it = null;
        // 设置 cookie
        for (int i = 0; i < cookie.size(); i++) {
            if (i > 0) {
                sb.append(";");
            }
            it = cookie.get(i);
            sb.append(it.getKey() + "=" + it.getValue());
        }
        if (sb.length() > 0) {
            conn.setRequestProperty("Cookie", sb.toString());
        }

    }

    protected void setResponseHeaderAndCookie(HttpURLConnection conn,
                                              Map<String, String> responseHeader,
                                              Map<String, String> responseCookie) {
        String field = conn.getHeaderField("Set-Cookie");
        // 设置响应 cookie
        if (!"".equals(field) && field != null) {
            for (String s : field.split(";")) {
                String[] split = s.split("=");
                String v = "";
                if (split.length == 2) {
                    v = split[1];
                }
                responseCookie.put(split[0], v);
            }
        }

        Map<String, List<String>> fields = conn.getHeaderFields();
        StringBuilder sb = null;

        // 设置响应头
        for (Map.Entry<String, List<String>> entry : fields.entrySet()) {
            HttpHeader header = new HttpHeader();

            header.setKey(entry.getKey());

            List<String> value = entry.getValue();
            if (value != null && value.size() > 0) {
                sb = new StringBuilder();

                for (int i = 0; i < value.size(); i++) {
                    if (i > 0) {
                        sb.append(";");
                    }
                    sb.append(value.get(i));
                }
                header.setValue(sb.toString());


            } else {
                header.setValue("");
            }
            responseHeader.put(header.getKey(), header.getValue());
        }

    }

    /**
     * @param conn
     * @param param          请求参数
     * @param responseHeader
     * @param responseCookie
     * @return
     */
    private String doRequest(HttpURLConnection conn,
                             String method,
                             String param,
                             Map<String, String> responseHeader,
                             Map<String, String> responseCookie) {
        StringBuffer buffer = null;
        PrintWriter out = null;
        InputStream is = null;
        InputStreamReader isr = null;
        BufferedReader br = null;

        try {
            conn.connect();

            if (!"get".equalsIgnoreCase(method)) {
                out = new PrintWriter(new OutputStreamWriter(conn.getOutputStream(), "utf-8"));
                // 发送请求参数
                out.print(param);
                // flush输出流的缓冲
                out.flush();
            }


            //往服务器端写内容


            //读取服务器端返回的内容
            is = conn.getInputStream();
            isr = new InputStreamReader(is, "utf-8");
            br = new BufferedReader(isr);
            buffer = new StringBuffer();
            String line = null;
            while ((line = br.readLine()) != null) {
                buffer.append(line);
            }

            setResponseHeaderAndCookie(conn, responseHeader, responseCookie);

        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            try {
                if (br != null) {
                    br.close();
                }
                if (isr != null) {
                    isr.close();
                }
                if (is != null) {
                    is.close();
                }
                if (out != null) {
                    out.close();
                }
            } catch (Exception e) {

            }
        }
        return buffer.toString();
    }


}
